<?php
namespace App\Models;

use App\Models\ComModel;

class BlackModel extends ComModel
{

    public $tablename;

    public function __construct(...$param)
    {
        parent::__construct();
        $this->tablename = 'black';
    }

    public function add($data)
    {
        if (!$data['ip']) {
            return ams_rt(1, '请填写IP内容');
        } elseif ($data['endtime'] && !(date('Y-m-d', strtotime($data['endtime'])) == $data['endtime'])) {
            return ams_rt(1, '截至日期格式不正确');
        }

        $data = esc($data);

        $data['endtime'] = $data['endtime'] ? strtotime($data['endtime'] . ' 23:59:59') : 0;
        $data['ip'] = str_replace(' ', '', $data['ip']);

        $flag = $this->db->table($this->tablename)->where('ip', $data['ip'])->countAllResults();
        if ($flag) {
            return ams_rt(1, '数据已存在');
        }

        //ip格式验证
        $ip = explode('-', $data['ip']);
        if (is_array($ip) && count($ip) == 2) {
            if (!filter_var($ip[0], FILTER_VALIDATE_IP) || !filter_var($ip[1], FILTER_VALIDATE_IP) || ip2long($ip[0]) > ip2long($ip[1])) {
                return ams_rt(1, 'IP地址段格式错误');
            }
            $data['type'] = 1;
            $data['startip'] = ip2long($ip[0]);
            $data['endip'] = ip2long($ip[1]);
        } elseif (filter_var($data['ip'], FILTER_VALIDATE_IP)) {
            $data['intip'] = ip2long($data['ip']);
            $data['type'] = 0;
        } else {

            $ip = explode('.', $data['ip']);
            if (is_array($ip) && count($ip) == 4) {

                foreach ($ip as $k => $v) {
                    if ($v != '*' && ($v < 0 || $v > 255)) {
                        return ams_rt(1, 'IP*地址段格式错误');
                    }
                }
                if ($ip[0] == '*') {
                    return ams_rt(1, 'IP*地址段格式错误');
                }

            } else {
                return ams_rt(1, 'IP地址段格式错误');
            }
            $data['type'] = 2;
        }

        $idata = [
            'ip' => $data['ip'],
            'intip' => $data['intip'] ?? 0,
            'type' => $data['type'] ?? 0,
            'startip' => $data['startip'] ?? 0,
            'endip' => $data['endip'] ?? 0,
            'endtime' => $data['endtime'] ?? 0,
            'status' => 1,
        ];

        $this->db->table($this->tablename)->insert($idata);
        $id = $this->db->insertID();
        if ($id) {
            $this->cacheData();
            return ams_rt(0, '操作成功', $idata);
        }
        return ams_rt(1, '操作失败', $data);

    }

    //修改
    public function edit($id, $data)
    {

        if (!$data['ip']) {
            return ams_rt(1, '请填写IP内容');
        } elseif ($data['endtime'] && !(date('Y-m-d', strtotime($data['endtime'])) == $data['endtime'])) {
            return ams_rt(1, '截至日期格式不正确');
        }

        $data = esc($data);

        $data['endtime'] = $data['endtime'] ? strtotime($data['endtime'] . ' 23:59:59') : 0;
        $data['ip'] = str_replace(' ', '', $data['ip']);

        $flag = $this->db->table($this->tablename)->where('id<>' . $id)->where('ip', $data['ip'])->countAllResults();
        if ($flag) {
            return ams_rt(1, '数据已存在');
        }

        //ip格式验证
        $ip = explode('-', $data['ip']);
        if (is_array($ip) && count($ip) == 2) {
            if (!filter_var($ip[0], FILTER_VALIDATE_IP) || !filter_var($ip[1], FILTER_VALIDATE_IP) || ip2long($ip[0]) > ip2long($ip[1])) {
                return ams_rt(1, 'IP地址段格式错误');
            }
            $data['type'] = 1;
            $data['startip'] = ip2long($ip[0]);
            $data['endip'] = ip2long($ip[1]);
        } elseif (filter_var($data['ip'], FILTER_VALIDATE_IP)) {
            $data['intip'] = ip2long($data['ip']);
            $data['type'] = 0;
        } else {

            $ip = explode('.', $data['ip']);
            if (is_array($ip) && count($ip) == 4) {

                foreach ($ip as $k => $v) {
                    if ($v != '*' && ($v < 0 || $v > 255)) {
                        return ams_rt(1, 'IP*地址段格式错误');
                    }
                }
                if ($ip[0] == '*') {
                    return ams_rt(1, 'IP*地址段格式错误');
                }

            } else {
                return ams_rt(1, 'IP地址段格式错误');
            }
            $data['type'] = 2;
        }

        $udata = [
            'ip' => $data['ip'],
            'intip' => $data['intip'] ?? 0,
            'type' => $data['type'] ?? 0,
            'startip' => $data['startip'] ?? 0,
            'endip' => $data['endip'] ?? 0,
            'endtime' => $data['endtime'] ?? 0,
        ];
        $this->db->table($this->tablename)->where('id', $id)->update($udata);
        $this->cacheData();
        return ams_rt(0, '操作成功', $data);
    }

    public function get($id)
    {
        $row = $this->db->table($this->tablename)->where('id', intval($id))->get()->getRowArray();
        if (!$row) {
            return [];
        }
        return $row;
    }

    public function del($id)
    {
        $this->db->table($this->tablename)->where('id', intval($id))->delete();
        $this->cacheData();
        return ams_rt(0, '操作成功');
    }

    /**
     * 条件查询
     */
    private function _where(&$select, $data)
    {
        if ($data) {
            if (isset($data['status']) && ($data['status'] || $data['status'] == '0')) {
                $select->where('status', $data['status']);
            }
            // 时间搜索
            if (isset($data['start']) && $data['start']) {
                $data['end'] = strtotime(date('Y-m-d 23:59:59', $data['end'] ? $data['end'] : time()));
                $data['start'] = strtotime(date('Y-m-d 00:00:00', $data['start']));
                $select->where('addtime BETWEEN ' . $data['start'] . ' AND ' . $data['end']);
            } elseif (isset($data['end']) && $data['end']) {
                $data['end'] = strtotime(date('Y-m-d 23:59:59', $data['end']));
                $data['start'] = 1;
                $select->where('addtime BETWEEN ' . $data['start'] . ' AND ' . $data['end']);
            }
        }
        return $data;
    }

    /**
     * 数据分页显示
     */
    public function limit_page($page = 0, $size = 10, $total = 0, $param = [])
    {
        if ($param) {
            $param = esc($param);
        }

        $page = max(1, (int) $page);
        $total = (int) $total;
        unset($param['page']);
        if ($size > 0 && !$total) {
            $select = $this->db->table($this->tablename)->select('count(*) as total');
            $param = $this->_where($select, $param);
            $query = $select->get();
            if (!$query) {
                log_message('error', '数据查询失败：' . $this->tablename);
                return [[], $total, $param];
            }
            $data = $query->getRowArray();
            $total = (int) $data['total'];
            $param['total'] = $total;
            unset($select);
            if (!$total) {
                return [[], $total, $param];
            }
        }

        $select = $this->db->table($this->tablename);
        $param = $this->_where($select, $param);
        $size > 0 && $select->limit($size, $size * ($page - 1));
        $query = $select->orderBy('id', 'asc')->get();
        if (!$query) {
            log_message('error', '数据查询失败：' . $this->tablename);
            return [[], $total, $param];
        }
        $data = $query->getResultArray();
        if ($data) {
            foreach ($data as $k => $v) {
                $data[$k]['endtime_date'] = $v['endtime'] ? date('Y-m-d', $v['endtime']) : '长期';
            }
        }
        $param['total'] = $total;
        return [$data, $total, $param];
    }

    public function switchStatus($id, $value)
    {
        if (!$id) {
            return ams_rt(1, '参数错误');
        }
        $row = $this->db->table($this->tablename)->select('id,ip,status')->where('id', $id)->get()->getRowArray();
        if (!$row) {
            return ams_rt(1, '数据不存在');
        }
        $this->db->table($this->tablename)->where('id', $id)->update(['status' => $value]);
        $this->cacheData();
        return ams_rt(0, '操作成功', $row);
    }

    public function getAll()
    {
        $rows = $this->db->table($this->tablename)->where('status', 1)->get()->getResultArray();
        if (!$rows) {
            $rows = [];
        }
        return $rows;
    }

    public function cacheData()
    {
        $cache = array();
        $list = $this->getAll();
        if ($list) {
            foreach ($list as $t) {
                $cache[$t['ip']] = $t;
            }
        }
        // 写入缓存
        $this->cache->save('blackip', $cache, YEAR);
        return $cache;
    }

}
